/************************************************************************

	FileDescription:	interface for RSA.
	FileVersion:		2006-09-09
	ProductVersion:		1, 0, 0, 1

	Portability:		ANSI C
	Base Classes:		None.
	Support DLL:		HugeCalc.dll ( V6.0.0.2 or above )
	Related Document:	HugeCalc.chm

	Copyright (c) 2006 by Guo XianQiang. All right reserved.

************************************************************************/

#if !defined(AFX_RSA_H__34130416_9155_483C_8291_ED09145ADA6F__INCLUDED_)
#define AFX_RSA_H__34130416_9155_483C_8291_ED09145ADA6F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif /* _MSC_VER > 1000 */

#include "../../../HugeCalc_API/Win32API/hugeCalc.h"

#define MINBITS				((UINT32)32)
#define MAXBITS				((UINT32)4096)
#define DEFAULTBITS			((UINT32)1024)

#define RSA_FASTTEST_STR	(_T("11"))
#define RSA_NORMALLY_STR	(_T("10001"))

typedef struct tagRSA
{
	HHUGEINTX E;	/* Encrypt Key E	*/
	HHUGEINTX P;	/* 1st Prime P		*/
	HHUGEINTX Q;	/* 2nd Prime Q		*/
	HHUGEINTX N;	/* Public  Key N	*/
	HHUGEINTX D;	/* Private Key D	*/

	HHUGEINTX OM;	/* Original Message	*/
	HHUGEINTX EM;	/* Encrypt Message	*/
	HHUGEINTX DM;	/* Decrypt Message	*/

	HHUGEINTX PIQ;	/* PIQ = P^(-1) mod Q	*/
	HHUGEINTX DP;	/* DP = D mod ( P - 1 )	*/
	HHUGEINTX DQ;	/* DQ = D mod ( Q - 1 )	*/

	BYTE byStatus;
	BOOL bHex;
}RSA, *LPRSA;

typedef enum tagRSAParam
{
	RSA_E,
	RSA_P,
	RSA_Q,
	RSA_N,
	RSA_D,
	RSA_OM,
	RSA_EM,
	RSA_DM,
}RSAParam;

#define BY_CHECK_E		0x01	/* E > 1 && E is an odd number? ( otherwise, Gcd(P-1, E) can't equal to 1 ) */
#define BY_CHECK_PQ		0x02	/* P <> Q ? */
#define BY_CHECK_P		0x04	/* P is a prime ? */
#define BY_CHECK_Q		0x08	/* Q is a prime ? */
#define BY_CHECK_P_1	0x10	/* Gcd( P-1, E ) == 1 ? */
#define BY_CHECK_Q_1	0x20	/* Gcd( Q-1, E ) == 1 ? */
#define BY_CHECK_M		0x80	/* OM < N ? */

#define BY_PxQ_N		0x40	/* N is not from set */

#define BY_PQ_OK		((BYTE) (~( BY_PxQ_N | BY_CHECK_M )))
#define BY_READY		((BYTE) (~BY_CHECK_M))

#define CHECK_FAIL_E(u)			( !( (u) & BY_CHECK_E ))
#define CHECK_FAIL_PQ(u)		( !( (u) & BY_CHECK_PQ ))
#define CHECK_FAIL_P(u)			( !( (u) & BY_CHECK_P ))
#define CHECK_FAIL_Q(u)			( !( (u) & BY_CHECK_Q ))
#define CHECK_FAIL_P_1(u)		( !( (u) & BY_CHECK_P_1 ))
#define CHECK_FAIL_Q_1(u)		( !( (u) & BY_CHECK_Q_1 ))
#define CHECK_FAIL_M(u)			( !( (u) & BY_CHECK_M ))

#define RSA_PQ_OK(u)			( BY_PQ_OK == ((u) & BY_PQ_OK ))
#define RSA_PxQ_N(u)			( BY_READY == ((u) & BY_PxQ_N ))
#define RSA_READY(u)			( BY_READY == ((u) & BY_READY ))


#ifdef  __cplusplus
extern "C"
{
#endif

	const BOOL RSA_Init( LPRSA pRSA );
	void RSA_free( LPRSA pRSA );

	void RSA_SetHex( LPRSA pRSA, const BOOL bHex /*= TRUE*/ );

	const BOOL RSA_GeneratePrime( LPRSA pRSA, UINT32 * const pKeyBits/* = NULL*/ );

	const BYTE RSA_SetParam( LPRSA pRSA, const LPCTSTR lpszString, const RSAParam enumRSAParam /*= RSA_OM*/ );
	const BYTE RSA_GetStatus( LPRSA pRSA );

	const LPCTSTR RSA_GetParam( const LPRSA pRSA, const RSAParam enumRSAParam /*= RSA_EM*/ );
	const UINT RSA_GetParamBits( const LPRSA pRSA, const RSAParam enumRSAParam /*= RSA_N*/ );

	const LPCTSTR RSA_EncryptMessage( LPRSA pRSA, const LPCTSTR lpszText );
	const LPCTSTR RSA_DecryptMessage( LPRSA pRSA, const LPCTSTR lpszHexNum );

#ifdef  __cplusplus
}
#endif

#endif /* !defined(AFX_RSA_H__34130416_9155_483C_8291_ED09145ADA6F__INCLUDED_) */
